﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ESP
{
    //////////////////////////////////////////////////////////////////////
//   Alan Oursland  
// 
//   ESP Java implementation.
//
//	 This code is a direct port of Faustino Gomez's ESP code
//   that was code started from Daniel Polani's translation of 
//   Dave Moriarty's original SANE code from C to C++.
//   
//   $Log: FullyRecurrentNetwork.java,v $
//////////////////////////////////////////////////////////////////////////
    public class FullyRecurrentNetwork : Network
    {
        public FullyRecurrentNetwork(int envInputCount, int neuronCount, int outputCount) :
            base(envInputCount, neuronCount, outputCount)
        {

        }

        public override void addNeuron()
        {
            addConnection(getTotalInputs() - 1);
            base.addNeuron();
        }

        public override void removeNeuron(int sp)
        {
            removeConnection(getInputCount() + sp);
            base.removeNeuron(sp);
        }

        private double[] tmp;

        public override void activate(double[] input, double[] output)
        {
            /* evaluate hidden/output layer */
            int relax = 2;

            for (int r = 0; r < relax; ++r)
            {
                tmp = new double[getInputCount() + activation.Length];
                Array.Copy(input, 0, tmp, 0, getInputCount());
                Array.Copy(activation, 0, tmp, getInputCount(), activation.Length);

                for (int i = 0; i < activation.Length; ++i)
                {
                    /*for each hidden unit*/
                    activation[i] = 0.0;
                    if (!getNeuron(i).lesioned)
                    {
                        for (int j = 0; j < getTotalInputs(); ++j)
                        {
                            activation[i] += getNeuron(i).weight[j]*tmp[j];
                        }
                        activation[i] = sigmoid(activation[i]);
                    }
                }

                Array.Copy(activation, 0, output, 0, getOutputCount());
            }
        }

        public override void save(String filename)
        {
            saveText(filename + "_FR");
        }

        public override int getTotalInputs()
        {
            return getInputCount() + getNeuronCount();
        }

        public override int getGeneSize()
        {
            return getTotalInputs();
        }
    }
}
